import {showLoading} from "../../../utils/jk-utils";
import util from './utils/zl'
import ToBase64 from './utils/base64gb2312.js'

let _self;
export default {
	props: {
		print: {
			type: [String, Number],
			default: ''
		},
		printData: {
			type: Object,
			default() {
				return {};
			}
		}
	},
	data() {
		return {
			isActiveConnected: false, // 是否主动去断开的标识
			isConnected: false,
			blueState: false,
			connectionDevice: {},
			selectDeviceItem: {},
			blueList: [],
			isRun: false,
			show: false,
			connectLoading: false,
			jkWriteInfo: {},
			canvasWidth: 100,
			canvasHeight: 100,
			CPCLCommand: null,
			sendBufferData: null,
			sendCount: null
		};
	},
	watch: {
		print(newVal) {
			console.log('打印', newVal)
			_self.toWrite();
		},
		isConnected(newVal) {
			_self.$emit('device-state', newVal);
		}
	},
	methods: {
		// 分包
		cutCommand () {
			let data = _self.CPCLCommand
			let sendBufferData = [];
			let packageLength = 10;
			for (let i = 0; i < Math.ceil(data.length / packageLength); i++) {
				sendBufferData[i] = wx.base64ToArrayBuffer(ToBase64.encode64gb2312(data.substr(i * packageLength, packageLength)));
			}
			_self.sendBufferData = sendBufferData;
			console.log('分包', _self.sendBufferData)
		},
		createCPCLCommand () {
			/**
			 * TSPL指令
			 * */
			let boxW = 1144;
			let boxH = 1140;
			let boxX = 22;
			let boxY = 274;

			let leftLabelX = boxX + 10;
			let leftLabelY = boxY + 40;
			let rowGap = 144;

			let labelGapLine = 10; // label和左侧线的间距

			let h_lineX = boxX; // 横线
			let lineGap = 240;
			let first_v_lineX = boxX + lineGap; // 第1根竖线
			let second_v_lineX = first_v_lineX + 34; // 第2根竖线的X坐标
			let second_v_lineH = 430; // 第2根竖线的高度
			let lineW = boxW - 10;
			// let fontType = 'TSS24.BF2'
			let fontType = 'FONT001' // 打印机必须存在该字体
			let qrCode = this.printData.showQrCode ? `QRCODE 880,14,H,10,A,0,M2,"${this.printData.data.code}"` : '';
			let str = `START:
PAUSEACT:
SIZE 100mm,100mm
CLS
DIRECTION 1
DENSITY 15
BOX ${boxX},${boxY},${boxW},${boxH},5
TEXT ${leftLabelX},78,"${fontType}",0,3,3,"${this.printData.data.categoryName}"
${qrCode}
TEXT ${leftLabelX},${leftLabelY},"${fontType}",0,2,2,"商品名"
BAR ${h_lineX},${boxY + rowGap},${lineW},5
BAR ${first_v_lineX},${boxY},5,${boxH - boxY}
TEXT ${first_v_lineX + labelGapLine},${leftLabelY},"${fontType}",0,2,2,"${this.printData.data.productName}"

TEXT ${leftLabelX},${leftLabelY + rowGap},"${fontType}",0,2,2,"批号"
BAR ${h_lineX},${boxY + rowGap * 2},${lineW},5
TEXT ${first_v_lineX + labelGapLine},${leftLabelY + rowGap},"${fontType}",0,2,2,"${this.printData.data.batchCode}"

TEXT ${leftLabelX},${leftLabelY + rowGap * 2},"${fontType}",0,2,2,"成分"
BAR ${h_lineX},${boxY + rowGap * 3},${lineW},5

BAR ${second_v_lineX + lineGap},${boxY + rowGap * 3},5,${second_v_lineH}
TEXT ${first_v_lineX + labelGapLine},${leftLabelY + rowGap * 2},"${fontType}",0,2,2,"${this.printData.data.ingredient}"
BAR ${second_v_lineX + lineGap * 2},${boxY + rowGap * 3},5,${second_v_lineH}

TEXT ${leftLabelX},${leftLabelY + rowGap * 3},"${fontType}",0,2,2,"纸管"
TEXT ${first_v_lineX + labelGapLine},${leftLabelY + rowGap * 3},"${fontType}",0,2,2,"${this.printData.data.paperTubeList ? this.printData.data.paperTubeList.map(x => x.name).join() : ''}"
TEXT ${second_v_lineX + lineGap + labelGapLine},${leftLabelY + rowGap * 3},"${fontType}",0,2,2,"包装袋"
TEXT ${second_v_lineX + lineGap * 2 + labelGapLine},${leftLabelY + rowGap * 3},"${fontType}",0,2,2,"${this.printData.data.outerBagList ? this.printData.data.outerBagList.map(x => x.name).join() : ''}"
BAR ${h_lineX},${boxY + rowGap * 4},${lineW},5

TEXT ${leftLabelX},${leftLabelY + rowGap * 4},"${fontType}",0,2,2,"内膜袋"
TEXT ${first_v_lineX + labelGapLine},${leftLabelY + rowGap * 4},"${fontType}",0,2,2,"${this.printData.data.innerBagList ? this.printData.data.innerBagList.map(x => x.name).join() : ''}"
TEXT ${second_v_lineX + lineGap + labelGapLine},${leftLabelY + rowGap * 4},"${fontType}",0,2,2,"扎线"
TEXT ${second_v_lineX + lineGap * 2 + labelGapLine},${leftLabelY + rowGap * 4},"${fontType}",0,2,2,"${this.printData.data.bundleList ? this.printData.data.bundleList.map(x => x.name).join() : ''}"
BAR ${h_lineX},${boxY + rowGap * 5},${lineW},5

TEXT ${leftLabelX},${leftLabelY + rowGap * 5},"${fontType}",0,2,2,"净重"
TEXT ${first_v_lineX + labelGapLine},${leftLabelY + rowGap * 5},"${fontType}",0,2,2,"${this.printData.data.suttle || ''}"
TEXT ${second_v_lineX + lineGap + labelGapLine},${leftLabelY + rowGap * 5},"${fontType}",0,2,2,"日期"
TEXT ${second_v_lineX + lineGap * 2 + labelGapLine},${leftLabelY + rowGap * 5},"${fontType}",0,2,2,"${this.printData.data.belongDate ? this.printData.data.belongDate.replace(/-/g, '.') : ''}"

PRINT ${this.printData.printCount || 1},1
GOTO START`
			_self.CPCLCommand = str;
			console.log('组装打印数据', str)
			_self.cutCommand();
		},
		// 开始分批写入
		runWrite() {
			console.log('打印成功', _self.sendCount)
			wx.writeBLECharacteristicValue({
				deviceId: _self.connectionDevice.deviceId,
				serviceId: _self.jkWriteInfo.serviceId,
				characteristicId: _self.jkWriteInfo.writeId,
				// 这里的value是ArrayBuffer类型
				value: _self.sendBufferData[_self.sendCount],
				success() {
					_self.sendCount++;
					console.log('打印成功', _self.sendCount)
					if (_self.sendCount <= _self.sendBufferData.length - 1) {
						_self.runWrite();
					} else {
						_self.$emit('print-finish', false);
					}
				},
				fail(res) {
					console.log('打印失败', res)
				}
			})
		},
		toWrite() {
			if (_self.jkWriteInfo.serviceId && _self.jkWriteInfo.writeId) {
				_self.createCPCLCommand();
				let sendBufferData = _self.sendBufferData;
				_self.sendCount = 0;
				_self.runWrite(sendBufferData);
			}
		},
		getServiceId() {
			return new Promise(((resolve, reject) => {
				wx.getBLEDeviceServices({
					deviceId: _self.connectionDevice.deviceId,
					success(res) {
						console.log('获取蓝牙服务', res)
						resolve(res.services)
					},
					fail(err) {
						resolve(null);
					}
				});
			}))
		},
		getCharacteristics(serviceId) {
			console.log('服务项', serviceId)
			return new Promise(((resolve, reject) => {
				let notify_id,read_id;
				wx.getBLEDeviceCharacteristics({
					deviceId: _self.connectionDevice.deviceId,
					serviceId: serviceId,
					success (res) {
						res.characteristics.forEach(charItem => {
							if (charItem.properties.notify) notify_id = charItem.uuid;
							if(charItem.properties.write) {
								_self.jkWriteInfo.serviceId = serviceId;
								_self.jkWriteInfo.writeId = charItem.uuid;
								console.log('写入的参数', _self.jkWriteInfo)
							}
							if(charItem.properties.read) read_id = charItem.uuid;
							console.log('读取的特征值属性', charItem.properties.notify, charItem.properties.indicate)
							if(charItem.properties.notify && charItem.properties.indicate){
								read_id = charItem.uuid;
								console.log('特征值有通知和指示属性：', charItem.properties.notify, charItem.properties.indicate)
								// 启用蓝牙特征值变化时的 notify 功能，订阅特征（必须支持 notify 或者 indicate 才可以特征值的二进制数据调用）
								wx.notifyBLECharacteristicValueChange({
									deviceId: _self.connectionDevice.deviceId,
									serviceId,
									characteristicId: charItem.uuid,
									state: true,
									type: 'notification',
									complete(res) {
										console.log('通知开启成功', res)
									}
								})
							}
						});
						resolve(1);
					},
					fail(res){
						resolve(0);
						console.log(res);
					}
				})
			}))
		},
		// 获取蓝牙的传递数据
		async getBlueData() {
			let serviceList = await this.getServiceId();
			console.log('!!!!!!!!', serviceList)
			for (let i = 0; i < serviceList.length; i++) {
				await this.getCharacteristics(serviceList[i].uuid);
			}
			// 开启监听特征值数据变化事件(须先调用 wx.notifyBLECharacteristicValueChange 接口才能接收到)
			wx.onBLECharacteristicValueChange((characteristic) => {
				console.log('转换后3：', _self.ab2ascii(characteristic.value), parseFloat(_self.ab2ascii(characteristic.value)))
				_self.$emit('val', parseFloat(_self.ab2ascii(characteristic.value)))
			});
		},
		// 二进制流转ascii
		ab2ascii(buffer) {
			let str = Array.prototype.map.call(
				new Uint8Array(buffer),
				function(bit) {
					return String.fromCharCode(bit);
				}
			)
			return str.join('');
		},
		ab2hex(buffer) {
			let hexArr = Array.prototype.map.call(
				new Uint8Array(buffer),
				function (bit) {
					return ('00' + bit.toString(16)).slice(-2)
				}
			)
			return hexArr.join('');
		},
		// 开启监听蓝牙的连接状态事件(用于处理连接意外断开等异常情况)
		monitorBlueStateChange() {
			wx.onBLEConnectionStateChanged((res) => {
				console.log('监听设备连接状态', res, _self.isActiveConnected)
				_self.isConnected = res.connected;
				if (!res.connected) {
					// 排除手动断开
					if (!_self.isActiveConnected) {
						wx.showModal({
							title: `提示`,
							content: `蓝牙意外断开`,
							icon: 'error',
							showCancel: false,
							confirmText: '关闭',
							complete() {
								_self.isActiveConnected = false;
							}
						});
						_self.isConnected = false;
						_self.connectionDevice = {};
						_self.connectLoading = false;
					}
				}
			})
		},
		onJustSearchBlue() {
			_self.isRun = true;
			_self.startSearchBlueDevice();
		},

		//寻找到新设备的事件
		onBluetoothDeviceFound() {
			wx.onBluetoothDeviceFound((res) => {
				let arr = res.devices || [];
				if (!_self.blueList.length) {
					_self.blueList = arr;
				} else {
					_self.pushDevice(arr);
				}
			})
		},
		// 将设备添加到列表
		pushDevice(arr) {
			let ids = _self.blueList.map(x => x.deviceId);
			let newArr = arr.filter(newItem => {
				// 过滤已有和无设备名
				return !ids.includes(newItem.deviceId) && newItem.name && !newItem.name.includes('不支持') && !newItem.name.includes('未知');
			})
			_self.blueList = [
				..._self.blueList,
				...newArr
			];
		},
		// 判断是否开启蓝牙(如：手机蓝牙开关)
		isOpenBlue() {
			return new Promise(((resolve) => {
				let {bluetoothEnabled} = wx.getSystemInfoSync();
				_self.blueState = bluetoothEnabled;
				console.log('开始获取蓝牙服务')
				if (!_self.blueState) {
					wx.showToast({
						icon: 'error',
						title: '请打开蓝牙'
					});
				}
				resolve(bluetoothEnabled);
			}))
		},
		// 服务判活
		isAlive() {
			return new Promise(((resolve, reject) => {
				// 有，则判断是否活着
				wx.getBLEDeviceServices({
					deviceId: _self.selectDeviceItem.deviceId,
					success(res) {
						console.log('获取蓝牙服务-成功', res)
						_self.connectionDevice = wx.getStorageSync('bindBlueDevice');
						if (!_self.blueList.map(x => x.deviceId).includes(_self.connectionDevice.deviceId)) {
							_self.blueList.unshift(_self.connectionDevice);
						}
						_self.isConnected = true;
						// 获取蓝牙模块生效期间所有搜索到的蓝牙设备(含已连接的设备)
						wx.getBluetoothDevices({
							success(res) {
								_self.pushDevice(res.devices);
							}
						});
						resolve(1);
					},
					fail(err) {
						resolve(0);
						console.log('蓝牙服务-失败', err)
					},
				})
			}))
		},
		//停止蓝牙搜索
		stopSearchBlue() {
			return new Promise(((resolve, reject) => {
				wx.stopBluetoothDevicesDiscovery({
					success(res) {
						_self.isRun = false;
						resolve(res);
					},
					fail(err) {
						reject(err);
					}
				});
			}))
		},
		// 初始化蓝牙适配器
		initBluetoothAdapter() {
			return new Promise(((resolve, reject) => {
				// 先关闭蓝牙
				wx.closeBluetoothAdapter({
					complete: () => {
						//初始化蓝牙
						wx.openBluetoothAdapter({
							success: (res) => {
								_self.isRun = true;
								resolve(1)
							},
							fail: (res) => {
								resolve(0)
								wx.showModal({
									title: `蓝牙初始化失败`,
									content: '蓝牙未开启或适配器不可用',
									showCancel: false,
									confirmText: '关闭'
								})
							}
						})
					}
				});
			}))
		},
		onSelectDeviceItem(item) {
			_self.selectDeviceItem = item;
			console.log('选择', item)
			_self.isActiveConnected = true;
			if (_self.connectionDevice.deviceId) {
				if (_self.selectDeviceItem.deviceId === _self.connectionDevice.deviceId) {
					wx.showModal({
						title: '该设备已经连接',
						showCancel: false,
						confirmText: '确定'
					});
				} else {
					_self.closeBlueConnection().then(res => {
						console.log('断开响应', res)
						_self.createConnectionBlue(_self.selectDeviceItem);
					});
				}
			} else {
				//创建连接
				_self.createConnectionBlue(_self.selectDeviceItem);
			}
		},
		onActiveCloseBlue() {
			_self.selectDeviceItem = {};
			_self.isActiveConnected = true;
			_self.closeBlueConnection();
		},
		closeBlueConnection() {
			return new Promise(((resolve, reject) => {
				if (_self.connectionDevice.deviceId) {
					// 断开连接
					console.log('开始断开', _self.connectionDevice.deviceId, _self.isActiveConnected);
					wx.closeBLEConnection({
						deviceId: _self.connectionDevice.deviceId,
						success(res) {
							_self.isRun = false;
							wx.removeStorageSync('bindBlueDevice');
							_self.connectionDevice = {};
							wx.showToast({
								title: `已断开`,
								icon: 'success'
							})
							resolve(1)
						},
						fail(res) {
							console.log('断开失败', res)
							_self.isRun = false;
							wx.removeStorageSync('bindBlueDevice');
							_self.connectionDevice = {};
							resolve(0)
						}
					});
					_self.stopSearchBlue();
				} else {
					wx.removeStorageSync('bindBlueDevice');
					_self.connectionDevice = {};
					wx.showToast({
						title: `未连接,无需断开`,
						icon: 'error'
					})
				}
			}))
		},
		createConnectionBlue(item) {
			return new Promise(((resolve, reject) => {
				console.log('创建连接', item);
				_self.connectLoading = true;
				showLoading(true, `正在连接${item.name}`)
				wx.createBLEConnection({
					deviceId: item.deviceId,
					timeout: 5000,
					success: (res) => {
						console.log('蓝牙连接成功');
						_self.isActiveConnected = false;
						_self.connectLoading = false;
						_self.isRun = false;
						_self.isConnected = true;
						wx.showToast({
							title: `连接${item.name}成功`,
							icon: 'success'
						});
						wx.setStorageSync('bindBlueDevice', item);
						_self.connectionDevice = JSON.parse(JSON.stringify(item));
						_self.getBlueData();
						_self.monitorBlueStateChange();
						_self.connectionDevice = wx.getStorageSync('bindBlueDevice');
						if (!_self.blueList.map(x => x.deviceId).includes(_self.connectionDevice.deviceId)) {
							_self.blueList.unshift(_self.connectionDevice);
						}
						resolve(1);
					},
					fail: (res) => {
						_self.connectLoading = false;
						wx.showToast({
							icon: 'error',
							title: '蓝牙连接失败'
						})
						console.log("蓝牙连接失败:", res);
						resolve(0);
					}
				})
			}))
		},
		//开始搜寻附近的蓝牙设备
		startSearchBlueDevice() {
			_self.getSystemInfo();
			return new Promise(((resolve, reject) => {
				//开启蓝牙搜索
				wx.startBluetoothDevicesDiscovery({
					allowDuplicatesKey: false,
					success: (res) => {
						console.log(res, "开启蓝牙搜索");
						_self.onBluetoothDeviceFound()
						resolve(1)
					},
					fail: (res) => {
						resolve(0)
						console.log(res, "搜索蓝牙失败");
					}
				});
			}))
		},
		getSystemInfo() {
			const that = this;
			wx.getSystemInfo({
				success(res){
					if (res.platform.indexOf('android') !== -1) {
						wx.getLocation({
							success(res) {
								console.log('定位成功', res)
							},
							fail(res) {
								console.log('定位失败', res)
								/*wx.showModal({
									title: '提示',
									content: '请开启开启定位权限!'
								});*/
							}
						});
					}
					console.log('系统', res.platform, res.version)
				}
			})
		},
		async initBlue() {
			await this.isOpenBlue();
			// 判断是否缓存里是否有连接的设备ID
			if (wx.getStorageSync('bindBlueDevice')) {
				_self.selectDeviceItem = wx.getStorageSync('bindBlueDevice');
				let aliveState = await _self.isAlive();
				console.log('判活', aliveState)
				if (!aliveState) {
					// 死了，则重新连接
					// await _self.stopSearchBlue();
					let initBluetoothAdapterState = await _self.initBluetoothAdapter();
					// 适配器初始化成功
					if (initBluetoothAdapterState) {
						_self.isActiveConnected = true;
						await _self.createConnectionBlue(_self.selectDeviceItem);
					}
				} else {
					_self.getBlueData();
				}
			} else {
				// 没有，则去搜索
				let initBluetoothAdapterState = await _self.initBluetoothAdapter();
				// 适配器初始化成功
				if (initBluetoothAdapterState) {
					await _self.startSearchBlueDevice();
				}
			}
		}
	},
	mounted() {
		// this指向需要重新修正，否则会出现指向问题
		_self = this;
	}
}
